AWS CDK で Event bus の DLQ を簡単に設定可能になりました
こんにちは、製造ビジネステクノロジー部の若槻です。
AWS CDK の最近のリリースである v2.163.0 で、下記のアップデートが追加されていました。
events: dead letter queue for an Event Bus (#30628) (318eae6), closes #30531
Amazon EventBridge では、Event bus に関連付けた Rule により、データソースから受信したイベントをターゲットにルーティングさせることができます。
Event buses in Amazon EventBridge - Amazon EventBridge から引用
そして、Event bus ではイベントの処理に失敗したイベントをキャプチャするための DLQ (Dead Letter Queue) を設定することができます。これは Rule のターゲットに対して設定するものとは別物となっており、下記図では①の部分に該当します。
Using dead-letter queues to capture encrypted event errors in EventBridge - Amazon EventBridge から引用
そして今回の AWS CDK のアップデートにより、この Event bus の DLQ を L2 Construct により簡単に設定可能になりました。
試してみた
CDK パッケージのアップデート
AWS CDK モジュールを v2.163.0 以上にアップデートします。
npm i aws-cdk-lib@latest aws-cdk@latest
CDK 実装
カスタムの Event bus に DLQ を設定する CDK コードです。EventBus クラスで deadLetterQueue
プロパティを指定することで DLQ を設定できます。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as events from 'aws-cdk-lib/aws-events';
export class SampleApp extends cdk.Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
const dlq = new sqs.Queue(this, 'DLQ');
const bus = new events.EventBus(this, 'Bus', {
deadLetterQueue: dlq, // DLQ を設定
});
new events.Rule(this, 'Rule', {
eventBus: bus,
eventPattern: {
source: ['my.custom.source'],
},
});
}
}
CDK diff で差分を確認してみます。Event bus で DeadLetterConfig が追加されていることが確認できます。
$ npx cdk diff
start: Building 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
success: Built 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
start: Publishing 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
success: Published 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Stack SampleApp
Resources
[~] AWS::Events::EventBus Bus BusEA82B648
└─ [+] DeadLetterConfig
└─ {"Arn":{"Fn::GetAtt":["DLQ581697C4","Arn"]}}
✨ Number of stacks with differences: 1
上記をデプロイして、DLQ の設定を反映させます。
作成された Event bus です。ここで bus の DLQ の設定も確認したいところですが、残念ながらマネジメントコンソールからの確認方法は現在は提供されていないようです。
ちなみに Event rule にターゲットが設定されている場合はそちらに DLQ の設定がありますがこれは前述の図の②に該当するもので、別物となります。
Event bus の DLQ の動作確認
作成した Event bus に設定した DLQ の動作確認をしてみます。ここでは意図的にイベントを失敗させるために、bus に無効な KMS キーを設定します。
まず有効な KMS キーを bus に設定します。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as events from 'aws-cdk-lib/aws-events';
import * as kms from 'aws-cdk-lib/aws-kms';
export class SampleApp extends cdk.Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
const dlq = new sqs.Queue(this, 'DLQ');
const kmsKey = new kms.Key(this, 'Key');
const bus = new events.EventBus(this, 'Bus', {
deadLetterQueue: dlq,
kmsKey,
});
new events.Rule(this, 'Rule', {
eventBus: bus,
eventPattern: {
source: ['my.custom.source'],
},
});
}
}
作成した KMS キーを無効にします。
aws kms disable-key --key-id $KMS_KEY_ID
送信するイベントのファイルを作成します。
[
{
"Source": "my.custom.source",
"DetailType": "myDetailType",
"Detail": "{ \"key1\": \"value1\" }"
}
]
AWS CLI でイベントを送信すると、KMS キーが無効であるため配信が失敗したようです。
$ aws events put-events --entries file://event.json
{
"FailedEntryCount": 1,
"Entries": [
{
"ErrorCode": "KMSEncryptionException",
"ErrorMessage": "arn:aws:kms:ap-northeast-1:XXXXXXXXXXXX:key/fc772eec-30c8-4c1c-ad80-7668e5b81308 is disabled."
}
]
}
イベント送信後に bus に設定した DLQ の SQS キューからイベントの受信を試みてみましたが、取得はできませんでした。
$ aws sqs receive-message --queue-url $DLQ_URL
マネジメントコンソールから確認できる Event bus のメトリクスでも、他の配信のメトリクスは記録されていますが、「Invocation sent to DLQ」については記録が行われていません。
KMS キーが無効であることにより配信失敗したイベントは、DLQ には送信されないようです。実際に DLQ が動作するのは Event bus 自体で障害が発生しているなどの場合でしょうか。
おわりに
AWS CDK で Event bus の DLQ を簡単に設定可能になりました。
Event bus は既定では Default の bus が使われますが、今回の検証のようにカスタムの bus を使用する場合には DLQ を設定しておくことで、イベントの配信失敗時に対処することが可能となります。
以上